package org.example.contract.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import org.example.utils.Util;
import org.example.warehouse.domain.MallStoreDetail;
import org.example.warehouse.domain.SellStoreDetail;
import org.example.warehouse.domain.WarehouseStore;
import org.example.warehouse.mapper.MallStoreDetailMapper;
import org.example.warehouse.mapper.OrderDetailMapper;
import org.example.warehouse.mapper.SellStoreDetailMapper;
import org.example.warehouse.mapper.WarehouseStoreMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.example.contract.mapper.ContractProductMapper;
import org.example.contract.domain.ContractProduct;
import org.example.contract.service.IContractProductService;
import com.ruoyi.common.core.text.Convert;
import org.springframework.transaction.annotation.Transactional;

/**
 * 合同产品表Service业务层处理
 *
 * @author heeenlin
 * @date 2024-04-12
 */
@Service
public class ContractProductServiceImpl implements IContractProductService
{
    @Autowired
    private ContractProductMapper contractProductMapper;
    @Autowired
    private MallStoreDetailMapper mallStoreDetailMapper;
    @Autowired
    private WarehouseStoreMapper warehouseStoreMapper;
    @Autowired
    private SellStoreDetailMapper sellStoreDetailMapper;
    /**
     * 查询合同产品表
     *
     * @param contractProductId 合同产品表主键
     * @return 合同产品表
     */
    @Override
    public ContractProduct selectContractProductByContractProductId(Long contractProductId)
    {
        return contractProductMapper.selectContractProductByContractProductId(contractProductId);
    }

    /**
     * 查询合同产品表列表
     *
     * @param contractProduct 合同产品表
     * @return 合同产品表
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<ContractProduct> selectContractProductList(ContractProduct contractProduct)
    {
        return contractProductMapper.selectContractProductList(contractProduct);
    }

    /**
     * 新增合同产品表
     *
     * @param contractProduct 合同产品表
     * @return 结果
     */
    @Override
    public int insertContractProduct(ContractProduct contractProduct)
    {
        contractProduct.setCreateTime(DateUtils.getNowDate());
        return contractProductMapper.insertContractProduct(contractProduct);
    }

    /**
     * 修改合同产品表
     *
     * @param contractProduct 合同产品表
     * @return 结果
     */
    @Override
    @Transactional
    public int updateContractProduct(ContractProduct contractProduct)
    {
        Integer operationNum = contractProduct.getOperationNum();
        Integer remainNum = contractProduct.getRemainNum();

        if(Util.CONTRACT_TYPE_BUY.equals(contractProduct.getContractType())){//采购
            if(operationNum>remainNum){
                throw new ServiceException("本次入库超出待入库数量");
            }
            //1、库存
            editWarehouseStore(contractProduct);

            //2、增加入库详情记录
            String storeDetailNo =  getMallStoreDetailNo();
            insertMallStoreDetail(contractProduct, storeDetailNo);
        }

        if(Util.CONTRACT_TYPE_SELL.equals(contractProduct.getContractType())){//销售
            if(operationNum>remainNum){
                throw new ServiceException("本次出库超出待出库数量");
            }
            WarehouseStore houseStoreDB = getWarehouseStore(contractProduct);
            //1、库存
            editWarehouseStore(contractProduct,houseStoreDB);

            //2、增加出库详情记录
            String storeDetailNo =  getSellStoreDetailNo();
            insertSellStoreDetail(contractProduct, storeDetailNo, houseStoreDB);
        }

        contractProduct.setRemainNum(remainNum-operationNum);
        contractProduct.setUseNum(contractProduct.getUseNum()+operationNum);
        contractProduct.setRemark(null);
        return contractProductMapper.updateContractProduct(contractProduct);
    }
    private void insertSellStoreDetail(ContractProduct contractProduct, String storeDetailNo , WarehouseStore houseStoreDB) {

        SellStoreDetail storeDetail =new SellStoreDetail();

        storeDetail.setSellDetailNo(storeDetailNo);
        storeDetail.setOrderDetailId(contractProduct.getContractProductId());
        storeDetail.setContractId(contractProduct.getContractId()+"");
        storeDetail.setWarehouseId(1L);
        storeDetail.setProductId(contractProduct.getProductId());
        storeDetail.setNum(contractProduct.getOperationNum());
        storeDetail.setPrice(contractProduct.getPrice());
        storeDetail.setAverageMoney(houseStoreDB.getAverageMoney());
        storeDetail.setCreateBy(ShiroUtils.getUserId()+"");
        storeDetail.setCreateTime(DateUtils.getNowDate());
        storeDetail.setRemark(contractProduct.getRemark());
        storeDetail.setSupplierId(contractProduct.getSupplierId());
        sellStoreDetailMapper.insertSellStoreDetail(storeDetail);
    }

    private void editWarehouseStore(ContractProduct contractProduct, WarehouseStore houseStoreDB) {
        if(houseStoreDB ==null || houseStoreDB.getWarehouseStoreId()<=0){
            throw new RuntimeException("库存没有该产品存在");
        }else{
            //更新库存
            houseStoreDB.setUseNum(handNullValue(houseStoreDB.getUseNum())+ contractProduct.getOperationNum());
            if(houseStoreDB.getRemainNum()- contractProduct.getOperationNum()<0){
                throw new RuntimeException(houseStoreDB.getName()+"：库存不足，【库存数量："+ houseStoreDB.getRemainNum()+"】 【出库数量："+contractProduct.getOperationNum()+"】");
            }
            houseStoreDB.setRemainNum(handNullValue(houseStoreDB.getRemainNum())- contractProduct.getOperationNum());
            warehouseStoreMapper.updateWarehouseStore(houseStoreDB);
        }
    }

    private WarehouseStore getWarehouseStore(ContractProduct contractProduct) {
        WarehouseStore store=new WarehouseStore();
        store.setProductId(contractProduct.getProductId());
        store.setWarehouseId(1L);
        store.getParams().put("deptId",ShiroUtils.getSysUser().getDeptId());
        WarehouseStore houseStoreDB= warehouseStoreMapper.selectMallWarehouseStoreByProductId(store);
        return houseStoreDB;
    }
    private String getSellStoreDetailNo(){
        SellStoreDetail sellStoreDetail=new SellStoreDetail();
        sellStoreDetail.getParams().put("deptId",ShiroUtils.getSysUser().getDeptId());
        sellStoreDetail.setCreateTime(DateUtils.getNowDate());
        SellStoreDetail storeDB = sellStoreDetailMapper.selectSellStoreDetailCount(sellStoreDetail);
        String storeDetailNo =  "GI"+DateUtils.dateTimeNow("yyMMdd")+String.format("%04d", storeDB.getNum()+1);
        return storeDetailNo;
    }
    private String getMallStoreDetailNo(){
        MallStoreDetail mallStoreDetail=new MallStoreDetail();
        mallStoreDetail.getParams().put("deptId",ShiroUtils.getSysUser().getDeptId());
        mallStoreDetail.setCreateTime(DateUtils.getNowDate());
        MallStoreDetail storeDB = mallStoreDetailMapper.selectMallStoreDetailCount(mallStoreDetail);
        String storeDetailNo =  "GR"+DateUtils.dateTimeNow("yyMMdd")+String.format("%04d", storeDB.getNum()+1);
        return storeDetailNo;
    }
    private void insertMallStoreDetail(ContractProduct contractProduct, String storeDetailNo) {
        MallStoreDetail storeDetail =new MallStoreDetail();
        storeDetail.setStoreDetailNo(storeDetailNo);
        storeDetail.setContractId(contractProduct.getContractId());
        storeDetail.setOrderDetailId(contractProduct.getContractProductId());
        storeDetail.setWarehouseId(1L);
        storeDetail.setProductId(contractProduct.getProductId());
        storeDetail.setNum(contractProduct.getOperationNum());
        storeDetail.setPrice(contractProduct.getPrice());
        storeDetail.setCreateBy(ShiroUtils.getUserId()+"");
        storeDetail.setCreateTime(DateUtils.getNowDate());
        storeDetail.setRemark(contractProduct.getRemark());
        storeDetail.setSupplierId(contractProduct.getSupplierId());
        mallStoreDetailMapper.insertMallStoreDetail(storeDetail);
    }

    private void editWarehouseStore(ContractProduct contractProduct) {
        WarehouseStore store=new WarehouseStore();
        store.setProductId(contractProduct.getProductId());
        store.setWarehouseId(1L);
        store.getParams().put("deptId",ShiroUtils.getSysUser().getDeptId());
        WarehouseStore houseStoreDB= warehouseStoreMapper.selectMallWarehouseStoreByProductId(store);
        if(houseStoreDB !=null && houseStoreDB.getWarehouseStoreId()>0){
            //更新库存
            BigDecimal dbSumMoney=houseStoreDB.getAverageMoney().multiply(BigDecimal.valueOf(houseStoreDB.getRemainNum()));
            BigDecimal operationSumMoney =contractProduct.getPrice().multiply(BigDecimal.valueOf(contractProduct.getOperationNum()));
            BigDecimal sumMoney =dbSumMoney.add(operationSumMoney);
            Integer sumNum =houseStoreDB.getRemainNum()+contractProduct.getOperationNum();
            BigDecimal averageMoney =sumMoney.divide(BigDecimal.valueOf(sumNum),2,BigDecimal.ROUND_HALF_UP);
            houseStoreDB.setAverageMoney(averageMoney);//平均价

            houseStoreDB.setNum(houseStoreDB.getNum()+ contractProduct.getOperationNum());
            houseStoreDB.setRemainNum(handNullValue(houseStoreDB.getRemainNum())+ contractProduct.getOperationNum());
            warehouseStoreMapper.updateWarehouseStore(houseStoreDB);
        }else{
            //新增库存
            store.setNum(contractProduct.getOperationNum());
            store.setRemainNum(contractProduct.getOperationNum());
            store.setWarehouseId(1L);
            store.setCreateBy(ShiroUtils.getUserId()+"");
            store.setCreateTime(DateUtils.getNowDate());
            store.setCheckNum(contractProduct.getOperationNum());
            store.setAverageMoney(contractProduct.getPrice());
            warehouseStoreMapper.insertWarehouseStore(store);
        }
    }


    private Integer handNullValue(Integer value){

        if(value==null){
            return 0;
        }
        return value;
    }

    /**
     * 批量删除合同产品表
     *
     * @param contractProductIds 需要删除的合同产品表主键
     * @return 结果
     */
    @Override
    public int deleteContractProductByContractProductIds(String contractProductIds)
    {
        return contractProductMapper.deleteContractProductByContractProductIds(Convert.toStrArray(contractProductIds));
    }

    /**
     * 删除合同产品表信息
     *
     * @param contractProductId 合同产品表主键
     * @return 结果
     */
    @Override
    public int deleteContractProductByContractProductId(Long contractProductId)
    {
        return contractProductMapper.deleteContractProductByContractProductId(contractProductId);
    }
}
